#include "vtkFunctions.hpp"

namespace hms::vtk {

fs::path getBoundaryPath( const fs::path& caseDir ){
	return fs::path{ caseDir / boundaryNode }.replace_extension("xml");
}
fs::path getConstantFieldsPath( const fs::path& caseDir ){
	return fs::path{ caseDir / constNode }.replace_extension("xml");
}
fs::path getSourceFieldsPath( const fs::path& caseDir ){
	return fs::path{ caseDir / sourceNode }.replace_extension("xml");
}

fs::path getBindingFilePath(
	const fs::path& caseDir,
	const std::string& caseName
){
	return fs::path{ caseDir / caseName }.replace_extension(bindingExt);
}


std::string nodeString( const xml::XMLNode* node ){
	return lineNum(node) + ":\n" + errorTrace(node);
}

std::string errorTrace( const xml::XMLNode* node ){
	std::vector<std::string> nodeNames;
	/* if the passed in node is already the document, return early */
	if ( node->ToDocument() ){
		return "\t[root]";
	}
	/* go all the way up to the root node while collecting names and attributes */
	while ( !node->ToDocument() ){
		/* collect all attributes and their values */
		std::string attributes;
		for(
			const xml::XMLAttribute* a = node->ToElement()->FirstAttribute();
			a;
			a=a->Next()
		){
			attributes += " "s + a->Name() + "=\"" + a->Value() + "\"";
		}
		nodeNames.emplace_back(
			"<"s + node->Value() + std::move(attributes) + ">"
		);
		/* go up */
		node = node->Parent();
	};
	std::string trace { "\t" + nodeNames.back() };
	/* reverse the order for the final string */
	for ( size_t i { nodeNames.size() - 1 }; i>0; --i ){
		trace += "\n\t-> " + nodeNames[i-1];
	}
	return trace;
}

namespace internal {

std::string readAttrError( const xml::XMLElement* elem, const char* attribute ){
	return 
		"Could not retrieve value from attribute \""s + attribute
		+ "\" in\n" + nodeString(elem);
}

} // end namespace hms::vtk::internal

} // end namespace hms::vtk